package ar.fiuba.tp7552.buildadmin.dao.impl;

import java.util.Collection;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.springframework.transaction.annotation.Transactional;

import ar.fiuba.tp7552.buildadmin.dao.GastoDao;
import ar.fiuba.tp7552.buildadmin.dao.GenericDaoHibernate;
import ar.fiuba.tp7552.buildadmin.model.gastos.Gasto;
import ar.fiuba.tp7552.buildadmin.model.gastos.GastoCriteria;
import ar.fiuba.tp7552.buildadmin.model.gastos.GastoReal;
import ar.fiuba.tp7552.buildadmin.model.gastos.Prevision;
import ar.fiuba.tp7552.buildadmin.util.CalendarUtil;
import ar.fiuba.tp7552.buildadmin.util.Cast;

@Transactional
public class GastoDaoImpl extends GenericDaoHibernate<Gasto, Long> implements GastoDao {

	public GastoDaoImpl() {
		super(Gasto.class);
	}

	@Override
	public Collection<Gasto> find(GastoCriteria criteria) {
		Session session = this.getHibernateSession();
		Criteria hcrit;
		
		if ( StringUtils.isNotEmpty(criteria.getHierarchy()) ) {
			if ( criteria.getHierarchy().equals("Prevision")) {
				hcrit = session.createCriteria(Prevision.class);
			} else {
				hcrit = session.createCriteria(GastoReal.class);
			}
		} else{
			hcrit = session.createCriteria(Gasto.class);
		}
		
		if (criteria.getDesde() != null) {
			hcrit.add(Restrictions.or(
					Restrictions.ge("fecha", criteria.getDesde()),
					
					Restrictions.and(
						Restrictions.ge("mes", CalendarUtil.getMonth(criteria.getDesde())), 
						Restrictions.ge("anio", CalendarUtil.getYear(criteria.getDesde()))
					)
				)
			);
		}
		
		if (criteria.getHasta() != null) {
			hcrit.add(Restrictions.or(
					Restrictions.le("fecha", criteria.getHasta()),
					
					Restrictions.and(
						Restrictions.le("mes", CalendarUtil.getMonth(criteria.getHasta())), 
						Restrictions.le("anio", CalendarUtil.getYear(criteria.getHasta()))
					)
				)
			);
		}
		
		if (criteria.getComp() != null && criteria.getMonto() != null) {
			switch (criteria.getComp()) {
				case 1: hcrit.add(Restrictions.ge("monto", criteria.getMonto()));
					break;
				case 2: hcrit.add(Restrictions.le("monto", criteria.getMonto()));
					break;
				case 3: hcrit.add(Restrictions.eq("monto", criteria.getMonto()));
					break;
			}
		}
		
		if (StringUtils.isNotEmpty(criteria.getText())) {
			hcrit.add(Restrictions.disjunction()
				.add(Restrictions.ilike("detalle", criteria.getText(), MatchMode.ANYWHERE))
				.add(Restrictions.ilike("razonSocial", criteria.getText(), MatchMode.ANYWHERE))
				.add(Restrictions.ilike("nroFactura", criteria.getText(), MatchMode.ANYWHERE))
				.add(Restrictions.ilike("formaPago", criteria.getText(), MatchMode.ANYWHERE))
			);
		}
		
		if (criteria.getEdificio() != null)
			hcrit.add(Restrictions.eq("edificio", criteria.getEdificio()));
		
		if (criteria.getTipo() != null)
			hcrit.add(Restrictions.eq("tipo", criteria.getTipo()));
		
		if ( StringUtils.isNotEmpty(criteria.getConsolidado()) )
			hcrit.add(Restrictions.eq("consolidado", Boolean.valueOf(criteria.getConsolidado())));

		
		
		return Cast.collection(Gasto.class, hcrit.list());
	}
	
}
